/*
 * ============================================================================
 *
 *       Filename:  common.c
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  01/23/2018 07:03:20 PM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  jianxi sun (jianxi), ycsunjane@gmail.com
 *   Organization:  
 *
 * ============================================================================
 */
#include <stdio.h>
#include <stdint.h>
#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/types.h>

#include "common.h"

void *ss_malloc(size_t size)
{
	void *tmp = malloc(size);
	if (tmp == NULL)
		exit(EXIT_FAILURE);
	memset(tmp, 0, size);
	return tmp;
}

void *ss_realloc(void *ptr, size_t new_size)
{
	void *new = realloc(ptr, new_size);
	if (new == NULL) {
		free(ptr);
		ptr = NULL;
		exit(EXIT_FAILURE);
	}
	return new;
}

/* 创建线程 */
void safe_pthread_create(void *(*start_routine) (void *), void *arg)
{
	pthread_attr_t attr;
	pthread_t mythread;

	if(pthread_attr_init(&attr)) {
		exit(-1);
	}
	if(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) {
		exit(-1);
	}
	if(pthread_create(&mythread, &attr, start_routine, arg)) {
		exit(-1);
	}
}
/* 创建目录 */
int create_dir_recursive(const char *path)
{
	char tmp[256];
	char *p = NULL;
	size_t len;

	snprintf(tmp, sizeof(tmp), "%s", path);
	len = strlen(tmp);
	if (tmp[len - 1] == '/') {
		tmp[len - 1] = 0;
	}
	if(F_OK == access(path, F_OK)) {
		return 1;
	}
	for (p = tmp + 1; *p; p++) {
		if (*p == '/') {
			*p = 0;
			if (access(tmp, F_OK) != 0) {
				if (mkdir(tmp, 0777) != 0) {
					perror("创建目录失败");
					return -1;
				}
			}
			*p = '/';
		}
	}
	if (access(tmp, F_OK) != F_OK) {
		if (mkdir(tmp, 0777) != 0) {
			perror("创建目录失败");
			return -1;
		}
	}
	return 0;
}
/* Hex 打印 */
void dump_hex_c(const void *data, size_t size, size_t bytes_per_line)
{
	const uint8_t *bytes = (const uint8_t *)data;
	char ascii[17];  // 用于存储ASCII表示，+1用于'\0'

	// 处理空指针或零长度
	if (!data || size == 0) {
		printf("(null)\n");
		return;
	}

	// 确保每行字节数合理
	if (bytes_per_line == 0) bytes_per_line = 16;

	// 遍历所有数据
	for (size_t i = 0; i < size; i += bytes_per_line) {
		// 打印行偏移量
		printf("%08zx: ", i);
		// 打印十六进制部分
		for (size_t j = 0; j < bytes_per_line; j++) {
			if (i + j < size) {
				printf("%02x ", bytes[i + j]);
			} else {
				printf("   ");  // 不足部分用空格填充
			}

			// 每8字节后添加额外空格，提高可读性
			if ((j + 1) % 8 == 0) {
				printf(" ");
			}
		}
		// 构建并打印ASCII表示
		printf("| ");
		for (size_t j = 0; j < bytes_per_line && i + j < size; j++) {
			// 可打印ASCII字符
			if (bytes[i + j] >= 32 && bytes[i + j] <= 126) {
				ascii[j] = bytes[i + j];
			} else {
				ascii[j] = '.';  // 不可打印字符用'.'表示
			}
		}
		ascii[bytes_per_line < size ? bytes_per_line : size - i] = '\0';
		printf("%s\n", ascii);
	}
}
